go build で missing go.sum entry for module providing package ビルドが失敗したときの原因と対応
FargateへCI/CDの設定をCodePipelineで行っていました。CodeBuildでgo build
時に以下のエラーによりビルドが失敗しました。メッセージ内容からCodeBuildの設定を疑っていたのですがCodeBuildの問題ではなく知っていればミスしない箇所でした。そのエラーと対応内容を紹介します。
CodeBuildのビルドログより
0.371 main.go:5:2: missing go.sum entry for module providing package github.com/labstack/echo/v4/middleware (imported by sample2-webapp-service/webapp); to add:
12 ERROR: executor failed running [/bin/sh -c go build -o web-server .]: runc did not terminate sucessfully
failed to solve with frontend dockerfile.v0: failed to build LLB: executor failed running [/bin/sh -c go build -o web-server .]: runc did not terminate sucessfully
原因
- 注目すべきメッセージは赤文字ではないところ missing go.sum entry for module providing package
- 適切な
go.sum
ファイルがなかった
- 適切な
go build
前にgo mod tidy
でgo.sum
ファイルを作成・更新する必要があった- 実行環境はGo version 1.16
CodeBuildの設定
CodeBuildの設定は問題なかったのですが、ビルドステージが2個ある構成なので簡単に紹介します。
1つのレポジトリから2つビルドのステージを作成していました。1つはWebアプリコンテナ、もう1つはサイドカーとして起動するFireLens(Fluent Bit)です。
buildspec.yml
の内容はほぼ共通です。docker buildで指定するDockerfileが異なるパスにあるため差異があります。変数はCodePipelineから渡してアカウントIDや、ECRのリポジトリ名を設定しています。
version: 0.2 env: variables: DOCKER_BUILDKIT: "1" phases: pre_build: commands: - echo Logging in to Amazon ECR... - aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin ${ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com - REPOSITORY_URI=${ACCOUNT_ID}.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/${REPOSITORY_NAME} - IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-8) build: commands: - echo Build started on `date` - docker build -t $REPOSITORY_NAME:$IMAGE_TAG ./webapp - docker tag $REPOSITORY_NAME:$IMAGE_TAG $REPOSITORY_URI:$IMAGE_TAG post_build: commands: - echo Build completed on `date` - echo Pushing the Docker image... - docker push $REPOSITORY_URI:$IMAGE_TAG - printf '{"ImageURI":"%s"}' $REPOSITORY_URI:$IMAGE_TAG > imageDetail.json artifacts: files: imageDetail.json
レポジトリのディレクトリ構成は以下のとおりです。buildspec.yml
がディレクトリ違いで2個存在しています。
. ├── README.md ├── appspec.yml ├── firelens │ ├── Dockerfile │ ├── buildspec.yml │ └── extra.conf ├── taskdef.json └── webapp ├── Dockerfile ├── buildspec.yml ├── go.mod ├── go.sum ├── handler │ └── handler.go └── main.go
ビルドプロジェクトも別れています。
以下のエラーメッセージが赤文字で表示されていたこともあり、当初はCodeBuildのビルドプロジェクトの設定を疑っていましたが関係ありませんでした。
failed to solve with frontend dockerfile.v0: failed to build LLB: executor failed running [/bin/sh -c go build -o web-server .]: runc did not terminate sucessfully
Dockerfile
CodeBuildでエラーが発生したときのDockerfileです。 マルチステージビルドしているだけのシンプルな内容です。ローカルでは問題なくdocker buildできるのに、CodeBuildだとなぜ失敗するのか調べていました。
FROM public.ecr.aws/bitnami/golang:1.16 as builder WORKDIR /app COPY . . RUN go mod download RUN go build -o web-server . FROM gcr.io/distroless/base-debian10:latest WORKDIR /app COPY --from=builder /app/web-server /app/web-server EXPOSE 80 ENTRYPOINT ["/app/web-server"]
ローカル実行環境
項目 | バージョン |
---|---|
Go | 1.16.6 |
Docker | 20.10.7 |
macOS | 10.15.7 |
CodeBuildのログから赤文字のエラーメッセージに気を取らていたのですが、よくみるとgo.sum
がないというメッセージも出力されています。
0.371 main.go:5:2: missing go.sum entry for module providing package ...
go.sum
は.gitignore
に追加しています。ローカルには存在していますが、CodeCommitには存在していません。さらに調べてみるとGoのバージョン1.15まではgo build
時にgo.sum
が自動更新されていたのが、1.16からは更新されなくなった。
go mod tidyコマンドがgo.mod
を確認し不足しているエントリをgo.sum
に追加してくれることを知りました。つまり、go.sum
の作成・更新をしてくれる。不要になった依存関係を削除してくれることしか把握しておらず、go.sum
については意識すらしていませんでした。
というわけでgo build
前にgo mod tidyを追加した修正版です。
FROM public.ecr.aws/bitnami/golang:1.16 as builder WORKDIR /app COPY . . RUN go mod download RUN go mod tidy RUN go build -o web-server . FROM gcr.io/distroless/base-debian10:latest WORKDIR /app COPY --from=builder /app/web-server /app/web-server EXPOSE 80 ENTRYPOINT ["/app/web-server"]
解決
修正版のDockerfileをCodeCommitへPushし、CodePipelineでCodeBuildが走りました。
go build
は正常に完了しました。
#11 [builder 4/6] RUN go mod download #11 DONE 3.8s #12 [builder 5/6] RUN go mod tidy #12 DONE 0.6s #13 [builder 6/6] RUN go build -o web-server . #13 DONE 4.4s
その後、デプロイまで完了しました。
おわりに
以上、備忘録でした。たまに使ってみるとキャッチアップが全然できていないことに気付かされます。つい先日1.17がリリースされましたし、日々のキャッチアップが大切ですね。